package es.efor.ics.gev.model;

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Embeddable;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.Version;

import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;

/**
 * Un atributo en una accion de una fase asociada a un evento + valor
 * 
 * @author dlisbona
 */
@Entity
@Table(name = "VAL_ATRIBUTOS_ACCIONES")
public class AtributoAccionInformado extends BaseObject implements Serializable {

	/**
	 * Embedded composite identifier class that represents the primary key
	 * columns of the many-to-many join table.
	 */
	@Embeddable
	public static class Id implements Serializable {

		private static final long serialVersionUID = 4134519349628344160L;

		private Long eventoId;
		private Long faseId;
		private Long accionId;
		private Long atributoId;

		public Id() {
		}

		public Id(Long eventoId, Long faseId, Long accionId, Long atributoId) {
			this.eventoId = eventoId;
			this.faseId = faseId;
			this.accionId = accionId;
			this.atributoId = atributoId;
		}

		@Column(name = "EVENTO_ID")
		public Long getEventoId() {
			return eventoId;
		}

		public void setEventoId(Long eventoId) {
			this.eventoId = eventoId;
		}

		@Column(name = "FASE_ID")
		public Long getFaseId() {
			return faseId;
		}

		public void setFaseId(Long faseId) {
			this.faseId = faseId;
		}

		@Column(name = "ACCION_ID")
		public Long getAccionId() {
			return accionId;
		}

		public void setAccionId(Long accionId) {
			this.accionId = accionId;
		}

		@Column(name = "ATRIBUTO_ID")
		public Long getAtributoId() {
			return atributoId;
		}

		public void setAtributoId(Long atributoId) {
			this.atributoId = atributoId;
		}

		@Override
		public boolean equals(Object o) {
			if (o instanceof Id) {
				Id that = (Id) o;
				return this.eventoId.equals(that.eventoId)
						&& this.faseId.equals(that.faseId)
						&& this.atributoId.equals(that.atributoId)
						&& this.accionId.equals(that.accionId);
			} else {
				return false;
			}
		}

		@Override
		public int hashCode() {
			return eventoId.hashCode() 
			+ faseId.hashCode() 
			+ accionId.hashCode() 
			+ atributoId.hashCode();
		}

		@Override
		public String toString() {
			return new ToStringBuilder(this, ToStringStyle.DEFAULT_STYLE)
					.append("eventoId", this.eventoId)
					.append("faseId", this.faseId)
					.append("accionId",
							this.accionId)
					.append("atributoId", this.atributoId).toString();
		}

	}

	// static data
	private static final long serialVersionUID = -3389445633520393799L;

	// private instance data
	private Id id;
	private Evento evento;
	private Fase fase;
	private Accion accion;
	private AtributoMaestro atributo;
	private String valor;
	private Integer version;

	/**
	 * Construct an uninitialized <code>AtributoAccionInformado</code> (for runtime proxy
	 * generation in Hibernate).
	 */
	protected AtributoAccionInformado() {		
	}
	
	/**
	 * Construct an initialized <code>AtributoAccionInformado</code>.
	 * 
	 * @param evento
	 * @param fase
	 * @param accion
	 * @param atributo
	 * @param valor
	 */
	public AtributoAccionInformado(Evento evento, Fase fase, Accion accion,
			AtributoMaestro atributo, String valor) {
		this.evento = evento;
		this.fase = fase;
		this.accion = accion;
		this.atributo = atributo;
		this.valor = valor;

		// Set primary key
		this.id = new Id(evento.getId(), fase.getId(), accion.getId(), atributo.getId());
	}

	// ********************** Accessor Methods ********************** //

	@EmbeddedId
	public Id getId() {
		return id;
	}

	public void setId(Id id) {
		this.id = id;
	}

	@ManyToOne(fetch = FetchType.LAZY)
	@JoinColumn(name = "EVENTO_ID", insertable = false, updatable = false)
	@org.hibernate.annotations.ForeignKey(name = "FK_VAL_ATR_ACC_EVENTO_ID")
	public Evento getEvento() {
		return evento;
	}

	public void setEvento(Evento evento) {
		this.evento = evento;
	}

	@ManyToOne(fetch = FetchType.LAZY)
	@JoinColumn(name = "FASE_ID", insertable = false, updatable = false)
	@org.hibernate.annotations.ForeignKey(name = "FK_VAL_ATR_ACC_FASE_ID")
	public Fase getFase() {
		return fase;
	}

	public void setFase(Fase fase) {
		this.fase = fase;
	}
	
	@ManyToOne(fetch = FetchType.LAZY)
	@JoinColumn(name = "ACCION_ID", insertable = false, updatable = false)
	@org.hibernate.annotations.ForeignKey(name = "FK_VAL_ATR_ACC_ACCION_ID")
	public Accion getAccion() {
		return accion;
	}

	public void setAccion(Accion accion) {
		this.accion = accion;
	}

	@ManyToOne(fetch = FetchType.LAZY)
	@JoinColumn(name = "ATRIBUTO_ID", insertable = false, updatable = false)
	@org.hibernate.annotations.ForeignKey(name = "FK_VAL_ATR_ACC_ATRIBUTO_ID")
	public AtributoMaestro getAtributo() {
		return atributo;
	}

	public void setAtributo(AtributoMaestro atributo) {
		this.atributo = atributo;
	}

	@Column(name = "VALOR_ATRIBUTO")
	public String getValor() {
		return valor;
	}

	public void setValor(String valor) {
		this.valor = valor;
	}
	
	@Version
	@Column(name = "OBJ_VERSION")
	public Integer getVersion() {
		return version;
	}

	public void setVersion(Integer version) {
		this.version = version;
	}

	// ********************** Common Methods ********************** //

	@Override
	public int hashCode() {
		return id.hashCode();
	}

	@Override
	public boolean equals(Object o) {
		if (this == o)
			return true;
		if (o == null || getClass() != o.getClass())
			return false;
		final AtributoAccionInformado that = (AtributoAccionInformado) o;
		return id.equals(that.id);
	}

	@Override
	public String toString() {
		return new ToStringBuilder(this, ToStringStyle.DEFAULT_STYLE).append(
				"evento", this.getEvento()).append("accion", this.getAccion())
				.append("atributo", this.getAtributo()).append("valor",
						this.getValor()).toString();
	}

}
